package com.javasm.springmybatis.async;

import com.javasm.springmybatis.common.util.SpringContainerUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * @Author：longjinyi
 * @Version：1.0
 * @Date：2021/12/30-11:40
 * @Since:jdk1.8
 * @Description:
 */
//异步管理器：管理异步任务
//这个类的作用：管理threadPoolTaskExecutor(线程池执行器) 1.初始化  2.方法的执行
public class AsyncManager {

    //线程池任务执行器
    //ThreadPoolTaskExecutor 有线程池
    //AsyncManager这个类为什么要持有ThreadPoolTaskExecutor呢？
    //AsyncManager这个类的作用是管理异步任务，也就是管理线程池
    //所以AsyncManager这个类要持有ThreadPoolTaskExecutor
    //要管理ThreadPoolTaskExecutor，也就是要给它初始化或者是赋值
    //这里面就要用到单例模式，即只创建一次
    //单例模式要实现构造方法私有化，即构造方法只能当前类自己可以new，其他的new不了
    private static ThreadPoolTaskExecutor threadPoolTaskExecutor = null;

    //持有自己这个类的变量
    private static AsyncManager asyncmanager=null;

    //构造方法私有化
    //这个构造方法在什么时候去执行？
    //在new AsyncManager的时候去执行
    //在创建 AsyncManager 的对象的时候，需要给谁初始化？
    //需要给 AsyncManager 里面持有的属性进行赋值，如：要给 ThreadPoolTaskExecutor 进行赋值
    //创建对象的方式有两种：
    //1.通过手动 new 进行创建
    //2.通过spring容器进行创建
    //给ThreadPoolTaskExecutor进行初始化的时候，不是通过手动 new 进行创建，而是通过获取spring容器中它的对象
    //构造方法私有化，初始化 threadPoolTaskExecutor ，相当于给 threadPoolTaskExecutor 赋值，这个对象是从spring容器中获取的
    private AsyncManager(){

        //ThreadPoolTaskExecutor.class是从spring容器中获取ThreadPoolTaskExecutor的对象
        //所以SpringContainerUtils相当于spring容器，从这里获取到ThreadPoolTaskExecutor的对象，赋给这里声明的threadPoolTaskExecutor对象
        //相当于给threadPoolTaskExecutor初始化好了
        threadPoolTaskExecutor = SpringContainerUtils.getBean(ThreadPoolTaskExecutor.class);

        //拿到对象可以设置或者获取关于线程池的配置
        //也可以设置核心线程数的数量
//        threadPoolTaskExecutor.setCorePoolSize();
        //获取默认的核心线程数
        int corePoolSize = threadPoolTaskExecutor.getCorePoolSize();
        System.out.println("默认的核心线程数======"+corePoolSize);
    }

    //执行从spring容器中获取ThreadPoolTaskExecutor的对象的方法，需要new AsyncManager，那这个是什么时候去执行的？
    //在 AsyncManager 的内部根据条件asyncmanager判断这个对象是否为空，决定是否去new AsyncManager
    //因为有static，所以这个方法是单例的，new AsyncManager的时候相当于给AsyncManager进行初始化了，创建一次就可以了
    //同时，也就初始化了ThreadPoolTaskExecutor，执行了从spring容器中获取到ThreadPoolTaskExecutor的对象的方法。
    //最终，调用getInstance方法得到的AsyncManager的对象，这个对象里面已经包含了已经初始化好的ThreadPoolTaskExecutor的对象threadPoolTaskExecutor
    //别人不能new，但是可以提供一个方法来给别人自己的实例
    public static AsyncManager getInstance(){
        //null写在右边有利于防止漏写 = 号
        //每次调用该方法，都new 一个AsyncManager，这种做法不合适
        //所以在这里加一个判断
        if (null == asyncmanager) {
            return new AsyncManager();
        }
        return asyncmanager;
    }


    //这个execute方法是被当前类AsyncManager去管理的
    //该方法不是通过类名去调用的，所以不用加static
    //最终执行任务的是由对象threadPoolTaskExecutor去执行的
    public void execute(Runnable runnable) {
        //执行任务必须传多线程接口Runnable当参数，必须实现Runnable这个接口
        threadPoolTaskExecutor.execute(runnable);
    }
}
